home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Table / Sources / Content.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  23.8 KB  |  830 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Content.cpp
  4. //    Release Version:    $ ODF 3 $ 
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #ifndef CONTENT_H
  11. #include "Content.h"
  12. #endif
  13.  
  14. #ifndef PART_H
  15. #include "Part.h"
  16. #endif
  17.  
  18. #ifndef FRAME_H
  19. #include "Frame.h"
  20. #endif
  21.  
  22. #ifndef PROXY_H
  23. #include "Proxy.h"
  24. #endif
  25.  
  26. #ifndef SELECTION_H
  27. #include "Selection.h"
  28. #endif
  29.  
  30. #ifndef LINKING_H
  31. #include "Linking.h"
  32. #endif
  33.  
  34. #ifndef DEFINES_K
  35. #include "Defines.k"
  36. #endif
  37.  
  38. // ----- Framework Includes -----
  39.  
  40. #ifndef FWFRMING_H
  41. #include "FWFrming.h"
  42. #endif
  43.  
  44. #ifndef FWPRESEN_H
  45. #include "FWPresen.h"
  46. #endif
  47.  
  48. #ifndef FWITERS_H
  49. #include "FWIters.h"
  50. #endif
  51.  
  52. #ifndef FWKIND_H
  53. #include "FWKind.h"
  54. #endif
  55.  
  56. #ifndef FWMEMMGR_H
  57. #include "FWMemMgr.h"
  58. #endif
  59.  
  60. #ifndef FWSUSINK_H
  61. #include "FWSUSink.h"
  62. #endif
  63.  
  64. #ifndef FWSUUTIL_H
  65. #include "FWSUUtil.h"
  66. #endif
  67.  
  68. #ifndef FWODMISC_H
  69. #include "FWODMisc.h"
  70. #endif
  71.  
  72. #ifdef __MRC__
  73. // This is to go around a bug in MRC. It doesn't seems to see the extern
  74. // in Proxy.cpp
  75. FW_DEFINE_AUTO_TEMPLATE(FW_TRefCountedCollection, CTableProxy)
  76. #endif
  77.  
  78. //========================================================================================
  79. //    Segmentation
  80. //========================================================================================
  81.  
  82. #ifdef FW_BUILD_MAC
  83. #pragma segment odfTable
  84. #endif
  85.  
  86. //========================================================================================
  87. //    class CTablePartContent
  88. //========================================================================================
  89.  
  90. FW_DEFINE_AUTO(CTablePartContent)
  91.  
  92. //----------------------------------------------------------------------------------------
  93. //    CTablePartContent::CTablePartContent
  94. //----------------------------------------------------------------------------------------
  95.  
  96. CTablePartContent::CTablePartContent(Environment* ev, CTablePart* part) :
  97.     FW_CContent(ev, part),
  98.     fTablePart(part),
  99.     fProxys(NULL),
  100.     fExtent(FW_IntToFixed(kDrawingSizeX), FW_IntToFixed(kDrawingSizeY)),
  101.     fWidth(NULL),
  102.     fHeight(NULL)
  103. {
  104.     // ----- Create list of proxies -----
  105.     fProxys = FW_NEW(CTableProxyCollection, ());
  106.  
  107.     fMaxRowCol.fX = kMaxCols;
  108.     fMaxRowCol.fY = kMaxRows;
  109.     
  110.     AllocateArrays();
  111.     
  112.     FW_Fixed w = FW_RoundedToInt((fExtent.x / FW_IntToFixed(fMaxRowCol.fX)) - kPenWidth - FW_kFixedPos1);
  113.     FW_Fixed h = FW_RoundedToInt((fExtent.y / FW_IntToFixed(fMaxRowCol.fY)) - kPenHeight - FW_kFixedPos1);
  114.  
  115.     // ----- Initialize arrays
  116.     unsigned long s;
  117.     for(s=0; s < fMaxRowCol.fX; s++)
  118.         fWidth[s] = w;        
  119.         
  120.     for(s=0; s < fMaxRowCol.fY; s++)
  121.         fHeight[s] = h;
  122.  
  123.     // ----- Adjust fExtent
  124.     fExtent.x = FW_RoundedToInt((w + kPenWidth) * FW_IntToFixed(fMaxRowCol.fX) + kPenWidth);
  125.     fExtent.y = FW_RoundedToInt((h + kPenHeight) * FW_IntToFixed(fMaxRowCol.fY) + kPenHeight);
  126.     
  127.     FW_END_CONSTRUCTOR
  128. }
  129.  
  130. //----------------------------------------------------------------------------------------
  131. //    CTablePartContent::~CTablePartContent
  132. //----------------------------------------------------------------------------------------
  133.  
  134. CTablePartContent::~CTablePartContent()
  135. {
  136.     FW_START_DESTRUCTOR
  137.     
  138.     delete fProxys;  // Releases all the proxy's
  139.     DisposeArrays();
  140. }
  141.  
  142. //----------------------------------------------------------------------------------------
  143. //    CTablePartContent::ExternalizeKind
  144. //----------------------------------------------------------------------------------------
  145.  
  146. void CTablePartContent::ExternalizeKind(Environment* ev,
  147.                                 ODStorageUnit* storageUnit, 
  148.                                 FW_CKind* kind,
  149.                                 FW_StorageKinds storageKind,
  150.                                 FW_CPromise* promise,
  151.                                 FW_CCloneInfo* cloneInfo)
  152. {
  153. FW_UNUSED(kind);
  154. FW_UNUSED(storageKind);
  155. FW_UNUSED(promise);
  156.  
  157.     // ---- Write out grid info ----
  158.     FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, fTablePart->GetPartKind(ev)->GetType(ev));
  159.     FW_CWritableStream stream(suSink);
  160.  
  161.     stream << fMaxRowCol.fX;
  162.     stream << fMaxRowCol.fY;
  163.     stream.Write(fWidth, ((long)fMaxRowCol.fX) * sizeof(FW_Fixed));
  164.     stream.Write(fHeight, ((long)fMaxRowCol.fY) * sizeof(FW_Fixed));
  165.  
  166.     // ---- Write number of embedded parts ----
  167.     unsigned long partCount = fProxys->Count();
  168.     stream << partCount;
  169.  
  170.     // ---- Write out embedded frames ----
  171.     if (partCount > 0)
  172.     {
  173.         CTableProxyCollectionIterator iter(fProxys);
  174.         for (CTableProxy* proxy = iter.First(); iter.IsNotComplete(); proxy = iter.Next())
  175.         {
  176.             CCell cell = proxy->GetCell();
  177.             stream << cell.fX;
  178.             stream << cell.fY;
  179.             proxy->Externalize(ev, suSink->GetStorageUnitView(ev), cloneInfo);
  180.         }
  181.     }
  182.     
  183.     // ----- Externalize Link -----
  184.     if (storageKind == FW_kPartStorage)
  185.     {
  186.         //--- Write source and destination links, if any ---
  187.         CTableLinkManager* linkMgr = (CTableLinkManager*) fTablePart->GetLinkManager(ev);
  188.         linkMgr->ExternalizeLinks(ev, storageUnit, cloneInfo);
  189.     }
  190.  
  191.     // ----- Cleaned up end of value -----
  192.     FW_SUDeleteEndOfFocusedValue(ev, storageUnit);
  193. }
  194.  
  195. //----------------------------------------------------------------------------------------
  196. //    CTablePartContent::InternalizeKind
  197. //----------------------------------------------------------------------------------------
  198.  
  199. FW_Boolean CTablePartContent::InternalizeKind(Environment* ev,
  200.                                     ODStorageUnit* storageUnit, 
  201.                                     FW_CKind* kind,
  202.                                     FW_StorageKinds storageKind,
  203.                                     FW_CCloneInfo* cloneInfo)
  204. {
  205. FW_UNUSED(kind);
  206. FW_UNUSED(storageKind);
  207.  
  208.     // ---- Read grid info -----
  209.     FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, fTablePart->GetPartKind(ev)->GetType(ev));
  210.     FW_PBufferedSink sink(ev, suSink);
  211.     FW_CReadableStream stream(sink);
  212.  
  213.     stream >> fMaxRowCol.fX;
  214.     stream >> fMaxRowCol.fY;
  215.  
  216.     AllocateArrays();
  217.     
  218.     stream.Read(fWidth, ((long)fMaxRowCol.fX) * sizeof(FW_Fixed));
  219.     stream.Read(fHeight, ((long)fMaxRowCol.fY) * sizeof(FW_Fixed));
  220.  
  221.     // ---- Read number of embedded parts ----
  222.     unsigned long partCount;
  223.     stream >> partCount;
  224.  
  225.     // ---- Read embedded parts ----
  226.     CCell cell;
  227.     CTableProxy* proxy;
  228.     for (unsigned long i = 0; i < partCount; i++)
  229.     {
  230.         stream >> cell.fX;
  231.         stream >> cell.fY;
  232.         proxy = new CTableProxy(ev, fTablePart, this);
  233.         proxy->SetCell(cell);
  234.         FW_TRY
  235.         {
  236.             proxy->Internalize(ev, suSink->GetStorageUnitView(ev), cloneInfo);        // read part and embed it
  237.         }
  238.         FW_CATCH_BEGIN
  239.         FW_CATCH_EVERYTHING()
  240.         {
  241.             proxy->Release();
  242.             FW_THROW_SAME();
  243.         }
  244.         FW_CATCH_END
  245.         
  246.         this->AddProxy(proxy);
  247.         proxy->Release();
  248.     }
  249.  
  250.     if (storageKind == FW_kPartStorage)
  251.     {
  252.         // ----- Read link information -----
  253.         CTableLinkManager* linkMgr = (CTableLinkManager*) fTablePart->GetLinkManager(ev);
  254.         linkMgr->InternalizeLinks(ev, storageUnit);
  255.     }
  256.     
  257.     return true;
  258. }
  259.  
  260. //----------------------------------------------------------------------------------------
  261. //    CTablePartContent::DisposeArrays
  262. //----------------------------------------------------------------------------------------
  263.  
  264. void CTablePartContent::DisposeArrays()
  265. {
  266.     if (fWidth != NULL)
  267.         FW_CMemoryManager::FreeBlock((void*)fWidth);
  268.     fWidth = NULL;
  269.     
  270.     if (fHeight != NULL)
  271.         FW_CMemoryManager::FreeBlock((void*)fHeight);
  272.     fHeight = NULL;
  273. }
  274.  
  275. //----------------------------------------------------------------------------------------
  276. //    CTablePartContent::AllocateArrays
  277. //----------------------------------------------------------------------------------------
  278.  
  279. void CTablePartContent::AllocateArrays()
  280. {
  281.     DisposeArrays();
  282.     
  283.     fWidth = (FW_Fixed*)FW_CMemoryManager::AllocateBlock(((long)fMaxRowCol.fX) * sizeof(FW_Fixed));
  284.     fHeight = (FW_Fixed*)FW_CMemoryManager::AllocateBlock(((long)fMaxRowCol.fY) * sizeof(FW_Fixed));
  285. }
  286.  
  287. //----------------------------------------------------------------------------------------
  288. //    CTablePartContent::IsDataOnlyOneProxy
  289. //----------------------------------------------------------------------------------------
  290.  
  291. FW_MProxy* CTablePartContent::IsDataOnlyOneProxy(Environment* ev) const
  292. {
  293. FW_UNUSED(ev);
  294.     // This method is only called on the content object associated with the selection to
  295.     // test for the Single Embedded Frame case. The part content should just retur NULL.
  296.     
  297.     return NULL;
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. //    CTablePartContent::CellToProxy
  302. //----------------------------------------------------------------------------------------
  303.  
  304. CTableProxy* CTablePartContent::CellToProxy(const CCell& cell) const
  305. {
  306.     // Convert a cell to a Proxy pointer by iterating over the list of proxies
  307.     
  308.     CTableProxyCollectionIterator iter(fProxys);
  309.     for (CTableProxy* proxy = iter.First(); iter.IsNotComplete(); proxy = iter.Next())
  310.     {
  311.         if (proxy->GetCell() == cell)
  312.             return proxy;
  313.     }
  314.  
  315.     return NULL;
  316. }
  317.  
  318. //----------------------------------------------------------------------------------------
  319. //    CTablePartContent::GetCellSize
  320. //----------------------------------------------------------------------------------------
  321.  
  322. FW_Fixed CTablePartContent::GetCellSize(short c,FW_XYSelector direction) const
  323. {
  324.     return direction == FW_kHorizontal ? GetWidth(c) : GetHeight(c);
  325. }
  326.  
  327. //----------------------------------------------------------------------------------------
  328. //    CTablePartContent::GetWidth
  329. //----------------------------------------------------------------------------------------
  330.  
  331. FW_Fixed CTablePartContent::GetWidth(short c) const
  332. {
  333.     return (c < fMaxRowCol.fX ? fWidth[c] : kDefaultCellWidth);
  334. }
  335.  
  336. //----------------------------------------------------------------------------------------
  337. //    CTablePartContent::GetHeight
  338. //----------------------------------------------------------------------------------------
  339.  
  340. FW_Fixed CTablePartContent::GetHeight(short r) const
  341. {
  342.     return (r < fMaxRowCol.fY ? fHeight[r] : kDefaultCellHeight);
  343. }
  344.  
  345. //----------------------------------------------------------------------------------------
  346. //    CTablePartContent::SetWidth
  347. //----------------------------------------------------------------------------------------
  348.  
  349. void CTablePartContent::SetWidth(short c, FW_Fixed w)
  350. {
  351.     FW_ASSERT(c < fMaxRowCol.fX);
  352.     fWidth[c] = w;
  353. }
  354.  
  355. //----------------------------------------------------------------------------------------
  356. //    CTablePartContent::SetHeight
  357. //----------------------------------------------------------------------------------------
  358.  
  359. void CTablePartContent::SetHeight(short r, FW_Fixed h)
  360. {
  361.     FW_ASSERT(r < fMaxRowCol.fY);
  362.     fHeight[r] = h;
  363. }
  364.  
  365. //----------------------------------------------------------------------------------------
  366. //    CTablePartContent::AddProxy
  367. //----------------------------------------------------------------------------------------
  368.  
  369. void CTablePartContent::AddProxy(CTableProxy* proxy)
  370. {
  371.     fProxys->AddLast(proxy);
  372. }
  373.  
  374. //----------------------------------------------------------------------------------------
  375. //    CTablePartContent::RemoveProxy
  376. //----------------------------------------------------------------------------------------
  377.  
  378. void CTablePartContent::RemoveProxy(CTableProxy* proxy)
  379. {
  380.     fProxys->RemoveAndRelease(proxy);
  381. }
  382.     
  383. //----------------------------------------------------------------------------------------
  384. //    CTablePartContent::DeleteProxy
  385. //----------------------------------------------------------------------------------------
  386.  
  387.  
  388.     
  389. //----------------------------------------------------------------------------------------
  390. //    CTablePartContent::FindLocation
  391. //----------------------------------------------------------------------------------------
  392.  
  393. FW_Fixed CTablePartContent::FindLocation(short c, FW_XYSelector direction) const
  394. {
  395.     return direction == FW_kHorizontal ? FindLeft(c) : FindTop(c);
  396. }
  397.  
  398. //----------------------------------------------------------------------------------------
  399. //    CTablePartContent::FindLeft
  400. //----------------------------------------------------------------------------------------
  401.  
  402. FW_Fixed CTablePartContent::FindLeft(short col) const
  403. {
  404.     if (col >= fMaxRowCol.fX)
  405.         return fExtent.x;
  406.  
  407.     FW_Fixed x = kBorderWidth;
  408.     for(short c = 0; c < col; c += 1)
  409.         x += this->GetWidth(c) + kBorderWidth;
  410.     
  411.     return x;
  412. }
  413.  
  414. //----------------------------------------------------------------------------------------
  415. //    CTablePartContent::FindTop
  416. //----------------------------------------------------------------------------------------
  417.  
  418. FW_Fixed CTablePartContent::FindTop(short row) const
  419. {
  420.     if (row >= fMaxRowCol.fY)
  421.         return fExtent.y;
  422.     
  423.     FW_Fixed y = kBorderHeight;
  424.  
  425.     for(short r = 0; r < row; r += 1)
  426.         y += this->GetHeight(r) + kBorderWidth;
  427.     return y;
  428. }
  429.  
  430. //----------------------------------------------------------------------------------------
  431. //    CTablePartContent::FindRect
  432. //----------------------------------------------------------------------------------------
  433.  
  434. void CTablePartContent::FindRect(const CCell& cell, FW_CRect& rect) const
  435. {
  436.     FW_Fixed x = this->FindLeft(cell.fX);
  437.     FW_Fixed y = this->FindTop (cell.fY);
  438.  
  439.     rect.Set(x, y,
  440.              x + this->GetWidth(cell.fX),
  441.              y + this->GetHeight(cell.fY));
  442. }
  443.  
  444. //----------------------------------------------------------------------------------------
  445. //    CTablePartContent::HitTest
  446. //----------------------------------------------------------------------------------------
  447.  
  448. ETableLoc CTablePartContent::HitTest(Environment* ev, 
  449.                                      const FW_CMouseEvent& theMouseEvent,
  450.                                      FW_CView* view,
  451.                                       CCell& cell) const
  452. {
  453.     FW_CPoint where = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
  454.     view->FrameToViewContent(ev, where);    
  455.     return HitTest(ev, where, cell);
  456. }
  457.  
  458. //----------------------------------------------------------------------------------------
  459. //    CTablePartContent::FindCell
  460. //----------------------------------------------------------------------------------------
  461.  
  462. void CTablePartContent::FindCell(const FW_CPoint& where, CCell& cell) const
  463. {
  464.     if (where.x < FW_kFixed0)
  465.         cell.fX = 0;
  466.     else
  467.     {
  468.         short r = 0;
  469.         FW_Fixed x = FW_kFixed0;
  470.         while (TRUE)
  471.         {
  472.             x += kBorderWidth + this->GetWidth(r);
  473.             if (where.x < x ||  r == fMaxRowCol.fX)
  474.             {
  475.                 cell.fX = r;
  476.                 break;                
  477.             }
  478.             r++;
  479.         }
  480.     } 
  481.     
  482.     if (where.y < FW_kFixed0)
  483.         cell.fY = 0;
  484.     else
  485.     {
  486.         short r = 0;
  487.         FW_Fixed y = FW_kFixed0;
  488.         while (TRUE)
  489.         {
  490.             y += kBorderHeight + this->GetHeight(r);
  491.             if (where.y < y || r == fMaxRowCol.fY)
  492.             {
  493.                 cell.fY = r;
  494.                 break;                
  495.             }
  496.             r++;
  497.         }
  498.     } 
  499. }
  500.  
  501. //----------------------------------------------------------------------------------------
  502. //    CTablePartContent::HitTest
  503. //----------------------------------------------------------------------------------------
  504.  
  505. ETableLoc CTablePartContent::HitTest(Environment* ev, 
  506.                                      const FW_CPoint& where,
  507.                                       CCell& cell) const
  508. {
  509. FW_UNUSED(ev);
  510.     FindCell(where, cell);
  511.     
  512.     if (cell.fX == fMaxRowCol.fX || cell.fY == fMaxRowCol.fY)
  513.         return kTLNone;
  514.         
  515.     ETableLoc tl = kTLCell;
  516.  
  517.     FW_CRect cellRect;
  518.     FindRect(cell, cellRect);
  519.     
  520.     if (where.x <= cellRect.left)
  521.         tl += kTLLeftBorder;
  522.     else if (cellRect.right <= where.x)
  523.         tl += kTLRightBorder;
  524.  
  525.     if (where.y <= cellRect.top)
  526.         tl += kTLTopBorder;
  527.     else if (cellRect.bottom <= where.y)
  528.         tl += kTLBottomBorder;
  529.         
  530.     if (cell.fY == 0 && ((tl & kTLTopBorder) != 0))
  531.         tl = kTLNone;
  532.  
  533.     if (cell.fX == 0 && ((tl & kTLLeftBorder) != 0))
  534.         tl = kTLNone;
  535.  
  536.     if (cell.fY == fMaxRowCol.fY - 1 && ((tl & kTLBottomBorder) != 0))
  537.         tl = kTLNone;
  538.  
  539.     if (cell.fX == fMaxRowCol.fX - 1 && ((tl & kTLBottomBorder) != 0))
  540.         tl = kTLNone;
  541.             
  542.     return tl;
  543. }
  544.  
  545. //----------------------------------------------------------------------------------------
  546. //    CTablePartContent::Resize
  547. //----------------------------------------------------------------------------------------
  548.  
  549. void CTablePartContent::Resize(Environment* ev, const CCell& cell, ETableLoc tl, const FW_CPoint& delta)
  550. {
  551.     CCell topLeftCell(cell);
  552.     
  553.     if (delta.x != FW_kFixed0)
  554.     {
  555.         if ((tl & kTLLeftBorder) != 0)
  556.             topLeftCell.fX -= 1;
  557.         SetWidth(topLeftCell.fX, GetWidth (topLeftCell.fX) + delta.x);        
  558.     }
  559.     
  560.     if (delta.y != FW_kFixed0)
  561.     {
  562.         if ((tl & kTLTopBorder) != 0)
  563.             topLeftCell.fY -= 1;
  564.         SetHeight(topLeftCell.fY, GetHeight(topLeftCell.fY) + delta.y);
  565.     }
  566.     
  567.     // Move all embedded frames
  568.     CTableProxyCollectionIterator ite(fProxys);
  569.     for (CTableProxy* proxy = ite.First(); ite.IsNotComplete(); proxy = ite.Next())
  570.     {
  571.         // Get operations being performed
  572.         CCell frCell = proxy->GetCell();
  573.         FW_Boolean resizing = (frCell.fX == topLeftCell.fX || frCell.fY == topLeftCell.fY);
  574.         FW_Boolean moving   = (frCell.fX > topLeftCell.fX || frCell.fY > topLeftCell.fY);
  575.         
  576.         if (resizing || moving)
  577.             proxy->MoveEmbeddedFrames(ev, frCell);
  578.     }
  579.  
  580.     UpdateExtent(ev);
  581.     
  582.     fTablePart->Changed(ev);
  583. }
  584.  
  585. //----------------------------------------------------------------------------------------
  586. //    CTablePartContent::UpdateExtent
  587. //----------------------------------------------------------------------------------------
  588.  
  589. void CTablePartContent::UpdateExtent(Environment* ev)
  590. {
  591.     CCell cell(fMaxRowCol.fX - 1, fMaxRowCol.fY - 1);
  592.     FW_CRect cellRect;
  593.     FindRect(cell, cellRect);
  594.     
  595.     fExtent.x = cellRect.right + kPenWidth;
  596.     fExtent.y = cellRect.bottom + kPenHeight;
  597.     
  598.     FW_CPresentationFrameIterator ite(ev, fTablePart->GetTablePresentation(ev));
  599.     for (FW_CFrame* frame = ite.First(ev); ite.IsNotComplete(ev); frame = ite.Next(ev))
  600.         frame->GetContentView(ev)->SetExtent(ev, fExtent);
  601. }
  602.  
  603. //----------------------------------------------------------------------------------------
  604. //    CTablePartContent::AddEmbeddedFrameOrPart
  605. //----------------------------------------------------------------------------------------
  606.  
  607. void CTablePartContent::AddEmbeddedFrameOrPart(Environment* ev, 
  608.                                                 const CCell& selectionCell,
  609.                                                 FW_CEmbeddingFrame* scopeFrame,
  610.                                                 ODPart* embeddedPart, 
  611.                                                 ODFrame* embeddedFrame,
  612.                                                 ODShape* suggestedShape,
  613.                                                 ODTypeToken viewType)
  614. {
  615.     // A single embedded frame or a part has been internalized (Drag&Drop, Clipboard or Insert).
  616.     
  617.     FW_UNUSED(suggestedShape);
  618.     
  619.     CTableProxy* proxy = CellToProxy(selectionCell);
  620.     
  621.     FW_CRect rect;
  622.     FindRect(selectionCell, rect);
  623.     rect.Place(FW_kZeroPoint);
  624.  
  625.     FW_CAcquiredODShape aqShape = ::FW_NewODShape(ev, rect);
  626.  
  627.     // ----- Create the proxy -----
  628.     CTableProxy* newProxy = new CTableProxy(ev, fTablePart, this);
  629.     newProxy->SetCell(selectionCell);
  630.  
  631.     // ----- Step 6: Embed it -----
  632.     FW_TRY
  633.     {
  634.         if (embeddedPart != NULL)
  635.         {
  636.             newProxy->EmbedPart(ev, 
  637.                                 scopeFrame->GetPresentation(ev),
  638.                                 embeddedPart, 
  639.                                 kODFrameObject,        // I want persistent frames
  640.                                 aqShape,
  641.                                 viewType,
  642.                                 NULL,        // no presentation
  643.                                 0,            // group id
  644.                                 FALSE,        // IsOverlaid
  645.                                 FALSE);        // sub frame
  646.         }
  647.         else
  648.         {
  649.             newProxy->EmbedFrame(ev, 
  650.                                 scopeFrame,
  651.                                 embeddedFrame,
  652.                                 aqShape,
  653.                                 viewType);
  654.         }
  655.     }
  656.     FW_CATCH_BEGIN
  657.     FW_CATCH_EVERYTHING () {
  658.         // cleanup for Step 6
  659.         newProxy->Release();
  660.         FW_THROW_SAME ();
  661.     }
  662.     FW_CATCH_END
  663.  
  664.     // ----- Add the newProxy to the part -----
  665.     AddProxy(newProxy);
  666.     
  667.     // newProxy has been acquired in AddProxy.  Releasing it now avoids
  668.     // need for another try block around the rest of the code
  669.     newProxy->Release();
  670.     
  671.     // ----- Delete the old proxy if there was one in the cell
  672.     if (proxy != NULL)
  673.     {
  674.         proxy->DetachEmbeddedFrames(ev);
  675.         RemoveProxy(proxy);
  676.     }
  677.  
  678.     // ----- Select the new proxy -----
  679.     newProxy->SetSelectState(ev, TRUE);
  680.     
  681.     // ----- Change its hilite state -----
  682.     if (scopeFrame && scopeFrame->HasSelectionFocus(ev))
  683.         newProxy->ChangeHighlight(ev, kODFullHighlight, scopeFrame);
  684. }
  685.  
  686. //========================================================================================
  687. //    class CTableSelectionContent
  688. //========================================================================================
  689.  
  690. FW_DEFINE_AUTO(CTableSelectionContent)
  691.  
  692. //----------------------------------------------------------------------------------------
  693. //    CTableSelectionContent::CTableSelectionContent
  694. //----------------------------------------------------------------------------------------
  695.  
  696. CTableSelectionContent::CTableSelectionContent(Environment* ev, CTablePart* part, CTablePartContent* content) :
  697.     FW_CContent(ev, part),
  698.     fTableContent(content),
  699.     fTablePart(part),
  700.     fCell(0, 0)
  701. {
  702.     FW_END_CONSTRUCTOR
  703. }
  704.  
  705. //----------------------------------------------------------------------------------------
  706. //    CTableSelectionContent::~CTableSelectionContent
  707. //----------------------------------------------------------------------------------------
  708.  
  709. CTableSelectionContent::~CTableSelectionContent()
  710. {
  711.     FW_START_DESTRUCTOR
  712. }
  713.  
  714.  
  715. //----------------------------------------------------------------------------------------
  716. //    IsDataOnlyOneProxy
  717. //----------------------------------------------------------------------------------------
  718.  
  719. FW_MProxy* CTableSelectionContent::IsDataOnlyOneProxy(Environment* ev) const
  720. {
  721. FW_UNUSED(ev);
  722.     return fTableContent->CellToProxy(fCell);
  723. }
  724.  
  725. //----------------------------------------------------------------------------------------
  726. //    CTableSelectionContent::InternalizeKind
  727. //----------------------------------------------------------------------------------------
  728.  
  729. FW_Boolean CTableSelectionContent::InternalizeKind(Environment* ev,
  730.                                             ODStorageUnit* storageUnit, 
  731.                                              FW_CKind* kind,
  732.                                             FW_StorageKinds storageKind,
  733.                                             FW_CCloneInfo* cloneInfo)
  734. {
  735. FW_UNUSED(ev);
  736. FW_UNUSED(storageUnit);
  737. FW_UNUSED(kind);
  738. FW_UNUSED(storageKind);
  739. FW_UNUSED(cloneInfo);
  740.     // Should never be called because I always internalize a single embedded frame
  741.     return false;
  742. }
  743.  
  744. //----------------------------------------------------------------------------------------
  745. //    CTableSelectionContent::ExternalizeKind
  746. //----------------------------------------------------------------------------------------
  747.  
  748. void CTableSelectionContent::ExternalizeKind(Environment* ev,
  749.                                         ODStorageUnit* storageUnit, 
  750.                                         FW_CKind* kind,
  751.                                         FW_StorageKinds storageKind,
  752.                                         FW_CPromise* promise,
  753.                                         FW_CCloneInfo* cloneInfo)
  754. {
  755.     FW_UNUSED(storageKind);
  756.     FW_UNUSED(promise);
  757.  
  758.     CTableProxy* proxy = GetSelectedProxy(ev);
  759.     FW_ASSERT(proxy);
  760.     
  761.     FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, kind->GetType(ev));
  762.     proxy->Externalize(ev, suSink->GetStorageUnitView(ev), cloneInfo);
  763.     
  764.     FW_SUDeleteEndOfFocusedValue(ev, storageUnit);
  765. }
  766.  
  767. //----------------------------------------------------------------------------------------
  768. //    CTableSelectionContent::GetSelectedProxy
  769. //----------------------------------------------------------------------------------------
  770.  
  771. CTableProxy* CTableSelectionContent::GetSelectedProxy(Environment* ev) const
  772. {
  773. FW_UNUSED(ev);
  774.     return fTableContent->CellToProxy(fCell);
  775. }
  776.  
  777. //----------------------------------------------------------------------------------------
  778. //    CTableSelectionContent::IncorporateEmbeddedFrame
  779. //----------------------------------------------------------------------------------------
  780.  
  781. void CTableSelectionContent::IncorporateEmbeddedFrame(Environment* ev, 
  782.                                                       FW_CEmbeddingFrame* scopeFrame,
  783.                                                       ODFrame* embeddedFrame,
  784.                                                       ODShape* suggestedShape,
  785.                                                       ODTypeToken viewType)
  786. {
  787.     fTableContent->AddEmbeddedFrameOrPart(ev, 
  788.                                         GetCell(), 
  789.                                         scopeFrame, 
  790.                                         NULL,
  791.                                         embeddedFrame, 
  792.                                         suggestedShape, 
  793.                                         viewType);
  794. }
  795.  
  796. //----------------------------------------------------------------------------------------
  797. //    CTableSelectionContent::IncorporateEmbeddedPart
  798. //----------------------------------------------------------------------------------------
  799.  
  800. void CTableSelectionContent::IncorporateEmbeddedPart(Environment* ev, 
  801.                                                     FW_CEmbeddingFrame* scopeFrame,
  802.                                                     ODPart* embeddedPart,
  803.                                                     ODShape* suggestedShape,
  804.                                                     ODTypeToken viewType)
  805. {
  806.     fTableContent->AddEmbeddedFrameOrPart(ev, 
  807.                                         GetCell(), 
  808.                                         scopeFrame, 
  809.                                         embeddedPart, 
  810.                                         NULL, 
  811.                                         suggestedShape, 
  812.                                         viewType);
  813. }
  814.  
  815. //----------------------------------------------------------------------------------------
  816. //    CTableSelectionContent::AcquireSuggestedFrameShape
  817. //----------------------------------------------------------------------------------------
  818.  
  819. ODShape* CTableSelectionContent::AcquireSuggestedFrameShape(Environment* ev)
  820. {
  821.     // return the shape used for the kODPropSuggestedFrameShape property.
  822.     
  823.     FW_CRect rect;
  824.     fTableContent->FindRect(GetCell(), rect);
  825.  
  826.     return ::FW_NewODShape(ev, rect);
  827. }
  828.  
  829.  
  830.